package com.corpgovernment.organization.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.corpgovernment.api.organization.bo.SearchEmployeeInfoRequestBO;
import com.corpgovernment.api.organization.dto.request.QueryExpressAddressRequestDto;
import com.corpgovernment.api.organization.model.expressaddress.ExpressAddressVo;
import com.corpgovernment.api.organization.model.user.employee.OrgEmployeeVo;
import com.corpgovernment.common.base.JSONResult;
import com.corpgovernment.common.enums.DeliveryTypeEnum;
import com.corpgovernment.common.enums.LogLevelEnum;
import com.corpgovernment.common.enums.PayTypeEnum;
import com.corpgovernment.common.logging.LogUtil;
import com.corpgovernment.common.utils.BaseUtils;
import com.corpgovernment.organization.constant.OrganizationConst;
import com.corpgovernment.organization.controller.expressaddress.ExpressAddressController;
import com.corpgovernment.organization.entity.db.MbExpressAddress;
import com.corpgovernment.organization.entity.db.MbOrgInfo;
import com.corpgovernment.organization.service.IOrganizationEmployeeService;
import com.corpgovernment.organization.service.IOrganizationInfoService;
import com.ctrip.corp.obt.generic.utils.JsonUtils;
import com.ctrip.corp.obt.generic.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Slf4j
public class QueryExpressAddressService {

	@Autowired
	private IOrganizationEmployeeService organizationEmployeeService;
	@Autowired
	private IOrganizationInfoService organizationInfoService;
	@Autowired
	private ExpressAddressServiceImpl expressAddressService;

	/**
	 * 获取配送地址
	 */
	public JSONResult<ExpressAddressVo> queryExpressAddress(QueryExpressAddressRequestDto request) {
		// #1.统一支付  预订配送地址取值该预订人的部门里维护的默认地址。如果部门未维护则直接取值该公司地址。不向上寻址
		ExpressAddressVo expressAddressVo = new ExpressAddressVo();
		if (PayTypeEnum.ACCNT.getType().equals(request.getPayType())) {
            log.info("统一支付获取配送地址");
            MbExpressAddress currentExpressAddress = getOrgAddress(request.getUid(), request.getOrgId());
            if (currentExpressAddress == null){
                //没有配送地址则默认为无需配送
                currentExpressAddress = new MbExpressAddress();
            }
            expressAddressVo = JsonUtils.convert(currentExpressAddress, ExpressAddressVo.class);
            return JSONResult.success(expressAddressVo);
        }
        log.info("个人支付获取配送地址");
        expressAddressVo.setDeliveryType(DeliveryTypeEnum.PJS.getCode());
        MbExpressAddress expressAddress = expressAddressService.findUserRecentUseAddress(request.getUid());
        if (expressAddress == null) {
            log.info("个人地址为空，取公司地址");
            expressAddress = getOrgAddress(request.getUid(), request.getOrgId());
        }
        if (expressAddress != null) {
            expressAddressVo = JsonUtils.convert(expressAddress, ExpressAddressVo.class);
            expressAddressVo.setDeliveryType(DeliveryTypeEnum.PJS.getCode());
            LogUtil.logging(LogLevelEnum.Info, ExpressAddressController.class, "expressAddress ", "expressAddress ： " + JsonUtils.toJsonString(expressAddress), null);
            log.info("个人支付获取配送地址返回值[{}]", JsonUtils.toJsonString(expressAddressVo));
        }
        return JSONResult.success(expressAddressVo);
    }

    /**
     * 统一支付时，预订配送地址取值该预订人的部门里维护的默认地址。如果部门未维护则直接取值该公司地址。不向上寻址
     */
    public MbExpressAddress getOrgAddress(String uid, String orgId) {
		// 用户所属部门的配送地址信息
		List<MbExpressAddress> currentExpressAddressList = getOrgAddresses(uid, orgId);
		if (!BaseUtils.isNotNull(currentExpressAddressList)) {
			log.info("配送地址为空");
			return null;
		}
		currentExpressAddressList = currentExpressAddressList.stream().filter(p -> Integer.valueOf(0).equals(p.getIsCorporation())).collect(Collectors.toList());
		MbExpressAddress currentExpressAddress = currentExpressAddressList.stream().filter(p -> p.getIsDefault() != null).filter(p -> p.getIsDefault().equals(1)).findFirst().orElse(null);
		if (currentExpressAddress == null) {
			currentExpressAddress = currentExpressAddressList.stream().max(Comparator.comparing(MbExpressAddress::getDatachangeLasttime)).orElse(null);
		}
		if (currentExpressAddress == null) {
			return null;
		}
		OrgEmployeeVo orgEmployeeVo = organizationEmployeeService.searchEmployeeInfo(SearchEmployeeInfoRequestBO.create(uid, orgId));
		if (orgEmployeeVo != null) {
			//公司配送地址，收件人用预订人
			currentExpressAddress.setRecipientName(orgEmployeeVo.getName());
			currentExpressAddress.setRecipientPhone(orgEmployeeVo.getMobilePhone());
		}
		return currentExpressAddress;
	}

    /**
     * 统一支付时，预订配送地址取值该预订人的部门里维护的默认地址。如果部门未维护则直接取值该公司地址。不向上寻址
     */
    public List<MbExpressAddress> getOrgAddresses(String uid, String orgId){
        // 查询所有组织机构
        List<MbOrgInfo> allOrgInfo = organizationInfoService.listAll();
        Map<String, MbOrgInfo> mbOrgInfoMap = allOrgInfo.stream().distinct().collect(Collectors.toMap(MbOrgInfo::getOrgId, p -> p));
        // 查询一直到公司的orgIds
        List<String> orgIds = new ArrayList<>();
        findCurrentOrgToRecentCompanyAllDepartment(orgId, mbOrgInfoMap, orgIds);
        // 查询当前组织架构list的地址
        List<MbExpressAddress> expressAddressList = expressAddressService.findListByOrgIds(orgIds);
        Map<String, List<MbExpressAddress>> expressAddressMap = expressAddressList.stream().collect(Collectors.groupingBy(MbExpressAddress::getOrgId));
        // 用户所属部门的配送地址信息
        List<MbExpressAddress> currentExpressAddressList = expressAddressMap.get(orgId);
        if (BaseUtils.isNotNull(currentExpressAddressList)){
            return currentExpressAddressList;
        }
        return find(mbOrgInfoMap, expressAddressMap, orgId, true);
    }



    /**
     * 统一支付时，预订配送地址取值该预订人的部门里维护的默认地址。如果部门未维护则直接取值该公司地址。不向上寻址
     */
    public List<MbExpressAddress> getAddresses(String orgId){
        // 查询所有组织机构
        List<MbOrgInfo> allOrgInfo = organizationInfoService.listAll();
        Map<String, MbOrgInfo> mbOrgInfoMap = allOrgInfo.stream().distinct().collect(Collectors.toMap(MbOrgInfo::getOrgId, p -> p));
        // 查询一直到公司的orgIds
        List<String> orgIds = new ArrayList<>();
        findCurrentOrgToRecentCompanyAllDepartment(orgId, mbOrgInfoMap, orgIds);
        // 查询当前组织架构list的地址
        List<MbExpressAddress> expressAddressList = expressAddressService.findListByOrgIds(orgIds);
        Map<String, List<MbExpressAddress>> expressAddressMap = expressAddressList.stream().collect(Collectors.groupingBy(MbExpressAddress::getOrgId));
        // 用户所属部门的配送地址信息
        List<MbExpressAddress> currentExpressAddressList = expressAddressMap.get(orgId);
        if (BaseUtils.isNotNull(currentExpressAddressList)){
            return currentExpressAddressList;
        }
        return find(mbOrgInfoMap, expressAddressMap, orgId, true);
    }

    /**
     * 查询一直到公司的orgIds
     */
    private void findCurrentOrgToRecentCompanyAllDepartment(String orgId, Map<String, MbOrgInfo> orgInfoMap, List<String> returnList) {
        MbOrgInfo mbOrgInfo = orgInfoMap.get(orgId);
        String orgType = mbOrgInfo.getOrgType();
        String orgIdDb = mbOrgInfo.getOrgId();
        String parentId = mbOrgInfo.getParentId();
        if (orgType.equals(OrganizationConst.DEPARTMENT)) {
            returnList.add(orgIdDb);
            findCurrentOrgToRecentCompanyAllDepartment(parentId, orgInfoMap, returnList);
        } else {
            returnList.add(orgIdDb);
            return;
        }
    }

    /**
     * 从部门开始遍历，一直到最近子公司，找到一个地址就返回，否则返回null
     */
    private List<MbExpressAddress> find(Map<String, MbOrgInfo> orgInfoMap, Map<String, List<MbExpressAddress>> expressAddressMap, String orgId, boolean firstFlag) {
        List<MbExpressAddress> expressAddress = expressAddressMap.get(orgId);
        if (CollUtil.isNotEmpty(expressAddress)) {
            return expressAddress;
        } else {
            MbOrgInfo mbOrgInfo = orgInfoMap.get(orgId);
            if (mbOrgInfo == null) {
                return null;
            }
            // 如果向上没找到，且到了公司级别，直接返回null
            if (mbOrgInfo.getOrgType().equals(OrganizationConst.COMPANY) && !firstFlag) {
                return null;
            }
            // 第一次公司查找要放过，用一个标识控制是否是第一次
            if (mbOrgInfo.getOrgType().equals(OrganizationConst.COMPANY)) {
                firstFlag = false;
            }
            String parentId = mbOrgInfo.getParentId();
            return find(orgInfoMap, expressAddressMap, parentId, firstFlag);
        }
    }

    /**
     * 数据校验
     */
    private boolean checkData(MbExpressAddress expressAddress) {
        String provinceName = expressAddress.getProvinceName();
        String cityName = expressAddress.getCityName();
        String districtName = expressAddress.getDistrictName();
        String address = expressAddress.getAddress();
        String recipientName = expressAddress.getRecipientName();
        String recipientMobilePhone = expressAddress.getRecipientPhone();
        String postCode = expressAddress.getPostCode();
        if (StringUtils.isBlank(provinceName) &&
                StringUtils.isBlank(cityName) &&
                StringUtils.isBlank(districtName) &&
                StringUtils.isBlank(address) &&
                StringUtils.isBlank(recipientName) &&
                StringUtils.isBlank(recipientMobilePhone)) {
            return false;
        } else {
            return true;
        }
    }
}